/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.reporte.control;

import java.io.ByteArrayInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import org.reporte.modelo.DatoConexion;
import org.reporte.modelo.DatoParametroReporte;
import org.reporte.modelo.DatoReporte;
import org.reporte.modelo.DetalleDatoReporte;
import org.reporte.utils.JsfAyuda;

/**
 *
 * @author 43579648
 */
public class ProcesaDatosReporte {

    private Locale idioma;

    public ProcesaDatosReporte(Locale idiomaDesplegarMensajes) {
        idioma = idiomaDesplegarMensajes;
    }


    private DatoReporte datoReporte;
    private List<DatoParametroReporte> listaDatoParametroReportePermanente = new ArrayList<DatoParametroReporte>();
    private List<DatoParametroReporte> listaDatoParametroReporteDinamica = new ArrayList<DatoParametroReporte>();


    
    public void cargaDatosParametros(DatoReporte datoReporte) {
        this.datoReporte = datoReporte;
        //Obteniendo la lista de parametros configurados al reporte
        for (DatoParametroReporte dp : datoReporte.getReporte().getDatoParametroReporteList()) {
            if (dp.getOpcionParametroReporte().getNombre().contains(JsfAyuda.getPropertyValueFromConfigurationFile("dinamico"))) {
                getListaDatoParametroReporteDinamica().add(dp);
            } else {
                getListaDatoParametroReportePermanente().add(dp);
            }
        }
    }


    /***
     * Evalua si el reporte esta activo
     */
    public boolean isReporteActivo() throws Exception {
        //Validando reporte
        String reporteActivo = obtenerValorParametroReportePermanente(
                JsfAyuda.getPropertyValueFromConfigurationFile("reporteActivo")).toUpperCase();
        if (reporteActivo.toUpperCase().contains("N") || reporteActivo.toUpperCase().contains("FAL") || reporteActivo.contains("NO")) {
            return false;
        }
        return true;
    }


    /***
     * Evalua si el reporte tiene conexion con la BD
     */
    public boolean isReporteConexionBaseDatos() {
        try{
            String tieneConexionBD = obtenerValorParametroReportePermanente(
                    JsfAyuda.getPropertyValueFromConfigurationFile("conexionBaseDatos")).toUpperCase();
            if (tieneConexionBD.contains("N")
                    || tieneConexionBD.contains("FAL")
                    || tieneConexionBD.contains("NO")) {
                return false;
            } else {
                return true;
            }
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
    }

    public boolean isReporteDataSourceXML(){
        try{
        String tieneDataSourceXMl = obtenerValorParametroReportePermanente(
                JsfAyuda.getPropertyValueFromConfigurationFile("dataSourceXML")).toUpperCase();
        if (tieneDataSourceXMl.contains("N")
                || tieneDataSourceXMl.contains("FAL")
                || tieneDataSourceXMl.contains("NO")) {
            return false;
        } else {
            return true;
        }
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
    }

    private boolean isReporteConexionJNDI() {
        for (DatoConexion d : getDatoReporte().getReporte().getConexion().getDatoConexionList()) {
            if (d.getParametroConexion().getNombre().toUpperCase().contains("JNDI")) {
                return true;
            }
        }
        return false;
    }

    /**
     * Obtiene el Valor de el Parametro permanente definido en los parametros reporte
     * @param String nombre ParametroReporte
     * @return String Valor ParametroReporte permanente
     */
    private String obtenerValorParametroReportePermanente(String nombreParametro) throws Exception { //MODIFICADO
        DatoParametroReporte parametroReporte = null;
        String valor = null;
        for (DatoParametroReporte p : getListaDatoParametroReportePermanente()) {
            if (p.getOpcionParametroReporte().getParametroReporte().getNombre().equalsIgnoreCase(nombreParametro)) {
                parametroReporte = p;
                break;
            }
        }
        if (parametroReporte == null) {
            throw new Exception(
                    JsfAyuda.getPropertyValue("reporteParametroNoEncontrado", idioma).replace("{0}", nombreParametro).replace("{1}", getDatoReporte().getReporte().getNombre()));
        }

        valor = parametroReporte.getOpcionParametroReporte().getNombre();
        return valor;
    }

    private String obtenerValorDatoConexion(String nombreParametroConexion) {
        for (DatoConexion d : getDatoReporte().getReporte().getConexion().getDatoConexionList()) {
            if (d.getParametroConexion().getNombre().equalsIgnoreCase(nombreParametroConexion)) {
                return d.getValor();
            }
        }
        return null;
    }

    /**
     * Obtiene una entidad DatosReporte a partir del parametro ingresado
     * @param String nombre del parametro definido al reporte
     * @return Entidad DatosReporte coincidente con el parametro
     */
    private DetalleDatoReporte obtenerDetalleDatoReporteDesdeParametroDinamico(String parametroDinamico) { //MODIFICACION
        DetalleDatoReporte detalleDatoReporte = null;

        for (DetalleDatoReporte dato : getDatoReporte().getDetalleDatoReporteList()) {
            if (dato.getDetalleDatoReportePK().getParametroDinamico().equalsIgnoreCase(parametroDinamico)) {
                detalleDatoReporte = dato;
                break;
            }
        }
        return detalleDatoReporte;
    }

    public ByteArrayInputStream obtenerDataSourceReporteDetalleAsXML() throws Exception{
        DetalleDatoReporte det = obtenerDetalleDatoReporteDesdeParametroDinamico(JsfAyuda.getPropertyValueFromConfigurationFile("dataSourceXML"));
        return new ByteArrayInputStream(det.getObjeto());
    }


    public String obtenerDataSourceReporteEstructuraSeleccionXML() {
        DetalleDatoReporte det = obtenerDetalleDatoReporteDesdeParametroDinamico(JsfAyuda.getPropertyValueFromConfigurationFile("dataSourceXML"));
        return det.getValor();
    }

    public HashMap obtenerParametrosDinamicosReporte() throws Exception {
        HashMap parametros = new HashMap();
        validarReporteDatosParametro();
        for (DatoParametroReporte p : getListaDatoParametroReporteDinamica()) {
            parametros.put(p.getParametroDinamico(), obtenerDetalleDatoReporteDesdeParametroDinamico(p.getParametroDinamico()));
        }
        return parametros;
    }


    private void validarReporteDatosParametro() throws Exception{
        boolean comparador = false;
        for(DatoParametroReporte param : getListaDatoParametroReporteDinamica()){
            for(DetalleDatoReporte dato : getDatoReporte().getDetalleDatoReporteList()){
                if(dato.getDetalleDatoReportePK().getParametroDinamico().equalsIgnoreCase(param.getParametroDinamico())){
                    comparador = true;
                }
            }
            if(comparador)
                comparador = false;
            else
                throw new Exception(JsfAyuda.getPropertyValue("paginaGeneracionParametrosDesiguales", idioma).replace("{0}", param.getParametroDinamico()));
        }
    }

    public ByteArrayInputStream obtenerReporteBinario() {
        return new ByteArrayInputStream(getDatoReporte().getReporte().getFicheroReporte());
    }

    public String obtenerReporteNombre() {
        return getDatoReporte().getReporte().getNombreFichero();
    }

    public String obtenerReporteTipoGenerar() throws Exception {
        return obtenerValorParametroReportePermanente(JsfAyuda.getPropertyValueFromConfigurationFile("tipoReporte"));
    }

    public Connection obtenerConexionBaseDatos() throws Exception {
        if (isReporteConexionJNDI()) {
            return obtenerConexionJNDI();
        } else {
            return obtenerConexionBaseDatosParametrosJDBC();
        }
    }

    private Connection obtenerConexionJNDI() throws Exception {
        DataSource ds = null;
        Connection conn = null;
        try {
            Context initCtx = new InitialContext();
            ds = (DataSource) initCtx.lookup(obtenerValorDatoConexion(
                    JsfAyuda.getPropertyValueFromConfigurationFile("nombreJNDI")));
            conn = ds.getConnection();
            return conn;
        } catch (Exception e) {
            throw e;
        }
    }

    private Connection obtenerConexionBaseDatosParametrosJDBC() throws Exception {

        Connection connection = null;

        try {
            System.out.println("Cargando el driver de la conexion");
            Class.forName(obtenerValorDatoConexion(
                    JsfAyuda.getPropertyValueFromConfigurationFile("driverConexion")));
            System.out.println("Driver cargador exitosamente");
            System.out.println("Generando la conexion");
            connection = DriverManager.getConnection(
                    obtenerValorDatoConexion(
                    JsfAyuda.getPropertyValueFromConfigurationFile("urlConexion")),
                    obtenerValorDatoConexion(
                    JsfAyuda.getPropertyValueFromConfigurationFile("usuarioConexion")),
                    obtenerValorDatoConexion(
                    JsfAyuda.getPropertyValueFromConfigurationFile("contrasenaConexion")));
            System.out.println("Conexion generada exitosamente");
            return connection;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Error al cargar la conexion " + e.getMessage());
            throw new Exception(e);
        }

    }

    public DatoReporte getDatoReporte() {
        return datoReporte;
    }

    public void setDatoReporte(DatoReporte datoReporte) {
        this.datoReporte = datoReporte;
    }

    public List<DatoParametroReporte> getListaDatoParametroReporteDinamica() {
        return listaDatoParametroReporteDinamica;
    }

    public void setListaDatoParametroReporteDinamica(List<DatoParametroReporte> listaDatoParametroReporteDinamica) {
        this.listaDatoParametroReporteDinamica = listaDatoParametroReporteDinamica;
    }

    public List<DatoParametroReporte> getListaDatoParametroReportePermanente() {
        return listaDatoParametroReportePermanente;
    }

    public void setListaDatoParametroReportePermanente(List<DatoParametroReporte> listaDatoParametroReportePermanente) {
        this.listaDatoParametroReportePermanente = listaDatoParametroReportePermanente;
    }
}
